namespace Text2Rss.Tests
{
	#region Using Directives
	using System.Configuration;
	using ECM7.Migrator;
	using NHibernate;
	using NHibernate.ByteCode.Castle;
	using NHibernate.Cfg.Loquacious;
	using NHibernate.Connection;
	using NHibernate.Context;
	using NHibernate.Dialect;
	using NHibernate.Driver;
	using NUnit.Framework;
	using Text2Rss.Migrations.Release001;
	using Text2Rss.Web.Models;
	using Configuration = NHibernate.Cfg.Configuration;
	#endregion

	/// <summary>
	/// Class that allows tests to access the test database
	/// </summary>
	public class PersistanceFixture
	{
		private const string ConnectionStringName = "sqlText2RssDb";

		protected ISessionFactory SessionFactory { get; private set; }

		protected ISession CurrentSession
		{
			get { return SessionFactory.GetCurrentSession(); }
		}

		/// <summary>
		/// Creates session factory
		/// </summary>
		[TestFixtureSetUp]
		public virtual void FixtureSetUp()
		{
			SessionFactory = new Configuration()
				.CurrentSessionContext<ThreadStaticSessionContext>()
				.Proxy(x => x.ProxyFactoryFactory<ProxyFactoryFactory>())
				.DataBaseIntegration(x =>
									{
										x.AutoCommentSql = true;
										x.ConnectionProvider<DriverConnectionProvider>();
										x.Driver<SqlClientDriver>();
										x.ConnectionStringName = ConnectionStringName;
										x.ConnectionReleaseMode = ConnectionReleaseMode.OnClose;
										x.Dialect<MsSql2008Dialect>();
										x.LogFormatedSql = true;
										x.LogSqlInConsole = true;
									})
				.AddAssembly(typeof(User).Assembly)
				.BuildSessionFactory();
		}

		/// <summary>
		/// Clears DB and creates a new session
		/// </summary>
		[SetUp]
		public virtual void SetUp()
		{
			MigrateToLatestVersion();
			var session = SessionFactory.OpenSession();
			CurrentSessionContext.Bind(session);
		}

		/// <summary>
		/// Closes session
		/// </summary>
		[TearDown]
		public virtual void TearDown()
		{
			SessionFactory.GetCurrentSession().Close();
			CurrentSessionContext.Unbind(SessionFactory);
		}

		/// <summary>
		/// Update structure of the test database to the last version
		/// </summary>
		protected void MigrateToLatestVersion()
		{
			var migrator = new Migrator(
				"ECM7.Migrator.Providers.SqlServer.SqlServerTransformationProvider, ECM7.Migrator.Providers.SqlServer",
				ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString,
				typeof(Migration001_Users).Assembly);
			migrator.Migrate(0);
			migrator.Migrate();
		}
	}
}
